<template>
  <span>{{ progress }}</span>
</template>
<script lang="ts" setup>
import { onMounted, ref } from "vue";

const props = withDefaults(
  defineProps<{
    duration?: number; // 持续时长
    startValue: number; // 起始值
    endValue: number; // 终止值 终止值得比起始值大
  }>(),
  {
    duration: 3000,
  }
);

let progress = ref(props.startValue); // 展示值

const runAnimation = () => {
  let start, previousTimeStamp;
  let done = false;
  let multiple = (props.endValue - props.startValue) / props.duration;

  function step(timestamp) {
    if (start === undefined) {
      start = timestamp;
    }
    const elapsed = timestamp - start;

    if (previousTimeStamp !== timestamp) {
      const count = Math.min(
        Number.parseInt(String(multiple * elapsed + props.startValue)), // 变化值
        props.endValue
      );
      progress.value = count;
      if (count === props.endValue) done = true;
    }

    if (elapsed < props.duration) {
      // 在 duration 后停止
      previousTimeStamp = timestamp;
    }
    if (!done) {
      window.requestAnimationFrame(step);
    }
  }
  window.requestAnimationFrame(step);
};

defineExpose({
  runAnimation,
});
onMounted(() => {
  // runAnimation();
});
</script>
<style lang="less" scoped></style>
